﻿using JNPF.Basics.Models;
using JNPF.Data;
using JNPF.Data.Util;
using JNPF.Utils;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JNPF.Basics.Logic
{
    /// <summary>
    /// 流程任务
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2018-06-08 
    /// </summary>
    internal class FlowTaskService : DataFactory, FlowTaskIService
    {
        /// <summary>
        /// 列表（流程监控）
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<FlowTaskEntity>> GetMonitorList(PageInput input)
        {
            using (var db = this.Basic)
            {
                var queryWhere = ExtLinq.True<FlowTaskEntity>().And(m => m.Status > 0);
                var queryParam = input.queryJson.ToObject();
                //关键字（流程标题、流程编码）
                if (!input.keyword.IsEmpty())
                {
                    var keyword = input.keyword.ToString();
                    queryWhere = queryWhere.And(m => m.EnCode.Contains(keyword) || m.FullName.Contains(keyword));
                }
                //日期范围（近7天、近1月、近3月、自定义）
                if (!queryParam["startTime"].IsEmpty() && !queryParam["endTime"].IsEmpty())
                {
                    var startTime = CommonHelper.GetDateTime(queryParam["startTime"].ToString());
                    var endTime = CommonHelper.GetDateTime(queryParam["endTime"].ToString());
                    startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0, 0);
                    endTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, 23, 59, 59, 999);
                    queryWhere = queryWhere.And(t => t.StartTime >= startTime && t.StartTime <= endTime);
                }
                //所属流程
                if (!queryParam["flowId"].IsEmpty())
                {
                    var flowId = queryParam["flowId"].ToString();
                    queryWhere = queryWhere.And(m => m.FlowId.Equals(flowId));
                }
                //所属分类
                if (!queryParam["flowCategory"].IsEmpty())
                {
                    var flowCategory = queryParam["flowCategory"].ToString();
                    queryWhere = queryWhere.And(m => m.FlowCategory.Equals(flowCategory));
                }
                //发起人员
                if (!queryParam["creatorUserId"].IsEmpty())
                {
                    var creatorUserId = queryParam["creatorUserId"].ToString();
                    queryWhere = queryWhere.And(m => m.CreatorUserId.Equals(creatorUserId));
                }
                input.sidx = "StartTime";
                return await db.GetIQueryable<FlowTaskEntity>().Where(queryWhere).OrderByDescending(t => t.CreatorTime).GetPageResultAsync(input);

            }
        }
        /// <summary>
        /// 列表（我发起的）
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<FlowTaskEntity>> GetLaunchList(string userId, PageInput input)
        {
            using (var db = this.Basic)
            {
                var queryWhere = ExtLinq.True<FlowTaskEntity>().And(m => m.CreatorUserId == userId && m.FlowType == 0);
                var queryParam = input.queryJson.ToObject();
                //关键字
                if (!input.keyword.IsEmpty())
                {
                    var keyword = input.keyword;
                    queryWhere = queryWhere.And(m => m.EnCode.Contains(keyword) || m.FullName.Contains(keyword));
                }
                //日期范围（近7天、近1月、近3月、自定义）
                if (!queryParam["startTime"].IsEmpty() && !queryParam["endTime"].IsEmpty())
                {
                    var startTime = CommonHelper.GetDateTime(queryParam["startTime"].ToString());
                    var endTime = CommonHelper.GetDateTime(queryParam["endTime"].ToString());
                    startTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, 0, 0, 0, 0);
                    endTime = new DateTime(endTime.Year, endTime.Month, endTime.Day, 23, 59, 59, 999);
                    queryWhere = queryWhere.And(t => t.StartTime >= startTime && t.StartTime <= endTime);
                }
                //所属流程
                if (!queryParam["flowId"].IsEmpty())
                {
                    var flowId = queryParam["flowId"].ToString();
                    queryWhere = queryWhere.And(m => m.FlowId.Equals(flowId));
                }
                //所属分类
                if (!queryParam["flowCategory"].IsEmpty())
                {
                    var flowCategory = queryParam["flowCategory"].ToString();
                    queryWhere = queryWhere.And(m => m.FlowCategory.Equals(flowCategory));
                }
                input.sidx = "StartTime";
                return await db.GetIQueryable<FlowTaskEntity>().Where(queryWhere).OrderByDescending(t => t.CreatorTime).GetPageResultAsync(input);
            }
        }
        /// <summary>
        /// 列表（待我审批）
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<FlowTaskEntity>> GetWaitList(string userId, PageInput input)
        {
            using (var db = this.Basic)
            {
                var thisTime = DateTime.Now;
                var parameters = new List<DbParameter>();
                var sqlText = @"SELECT 
                                o.F_Id as F_Id,
                                t.F_ProcessId,
                                t.F_EnCode, 
                                t.F_FullName,
                                t.F_FlowUrgent,
                                t.F_FlowId , 
                                t.F_FlowCode , 
                                t.F_FlowName, 
                                t.F_FlowCategory, 
                                t.F_StartTime, 
                                t.F_EndTime, 
                                t.F_ThisStep, 
                                t.F_ThisStepId, 
                                t.F_Status ,
                                t.F_Completion,
                                t.F_CreatorUserId,
                                o.F_CreatorTime,
                                t.F_LastModifyUserId,
                                t.F_LastModifyTime
                                FROM Flow_Task t left join
                                Flow_TaskOperator o on o.F_TaskId = t.F_Id WHERE 1=1 AND o.F_Completion = 0 AND (t.F_Status = 1)";
                StringBuilder dbSql = new StringBuilder(sqlText);
                //经办审核
                dbSql.Append(" AND o.F_HandleId = '" + userId + "' ");
                //委托审核
                var flowDelegateList = await db.GetListAsync<FlowDelegateEntity>(m => m.ToUserId == userId && m.StartTime <= thisTime && m.EndTime >= thisTime);
                if (flowDelegateList.Count > 0)
                {
                    var delegateSqlText = sqlText.Replace("t.F_FullName,", "concat(t.F_FullName,'('+u.F_RealName+'的委托)') as F_FullName,")
                        .Replace("WHERE", "  left join flow_delegate d on t.F_FlowId=d.F_FlowId left join base_user u on d.F_CreatorUserId=u.F_Id  WHERE ");
                    var creatorUserIds = flowDelegateList.Select(x => x.CreatorUserId + x.FlowId).Distinct().ToList();//委托人id集合
                    var delegateSql = new StringBuilder(delegateSqlText);
                    delegateSql.Append(string.Format(@"AND  d.F_ToUserId ='{0}' and (o.F_HandleId+t.F_FlowId) in ('{1}')", userId, string.Join("','", creatorUserIds)));
                    dbSql.Append("  union  " + delegateSql.ToString());
                }
                dbSql = new StringBuilder(string.Format("select * from ({0}) x where 1=1", dbSql.ToString()));
                var queryParam = input.queryJson.ToObject();
                //关键字（流程标题、流程编码）
                if (!input.keyword.IsEmpty())
                {
                    dbSql.Append(" AND (F_EnCode like @keyword or F_FullName like @keyword)");
                    parameters.Add(DataHelper.CreateParameter("@keyword", '%' + input.keyword + '%'));
                }
                //日期范围（近7天、近1月、近3月、自定义）
                if (!queryParam["startTime"].IsEmpty() && !queryParam["endTime"].IsEmpty())
                {
                    var startTime = CommonHelper.GetDateTime(queryParam["startTime"].ToString());
                    var endTime = CommonHelper.GetDateTime(queryParam["endTime"].ToString());
                    dbSql.Append(" AND F_CreatorTime Between CONVERT(varchar(100), @startTime, 23) +' 00:00:00' and CONVERT(varchar(100), @endTime, 23) +' 23:59:59'");
                    parameters.Add(DataHelper.CreateParameter("@startTime", startTime));
                    parameters.Add(DataHelper.CreateParameter("@endTime", endTime));
                }
                //所属流程
                if (!queryParam["flowId"].IsEmpty())
                {
                    dbSql.Append(" AND F_FlowId = @flowId");
                    parameters.Add(DataHelper.CreateParameter("@flowId", queryParam["flowId"].ToString()));
                }
                //所属分类
                if (!queryParam["flowCategory"].IsEmpty())
                {
                    dbSql.Append(" AND F_FlowCategory = @flowCategory");
                    parameters.Add(DataHelper.CreateParameter("@flowCategory", queryParam["flowCategory"].ToString()));
                }
                //发起人员
                if (!queryParam["creatorUserId"].IsEmpty())
                {
                    dbSql.Append(" AND F_CreatorUserId = @creatorUserId");
                    parameters.Add(DataHelper.CreateParameter("@creatorUserId", queryParam["creatorUserId"].ToString()));
                }
                input.sidx = "F_StartTime";
                return await PageHelper.GetPageResultAsync<FlowTaskEntity>(db, input, dbSql.ToString(), parameters.ToArray());

            }
        }

        /// <summary>
        /// 列表（我已审批）
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<FlowTaskEntity>> GetTrialList(string userId, PageInput input)
        {
            using (var db = this.Basic)
            {
                var parameters = new List<DbParameter>();
                StringBuilder dbSql = new StringBuilder();
                dbSql.Append(@"SELECT 
                                r.F_Id AS F_Id, 
                                t.F_ProcessId,
                                t.F_EnCode, 
                                (CASE WHEN o.F_HandleId=r.F_HandleId THEN t.F_FullName 
                                ELSE concat( t.F_FullName, '(' + u.F_RealName + '的委托)' ) 
	                            END) F_FullName,
                                t.F_FlowUrgent,
                                t.F_FlowId , 
                                t.F_FlowCode , 
                                t.F_FlowName, 
                                t.F_FlowCategory, 
                                t.F_StartTime, 
                                t.F_EndTime, 
                                r.F_NodeName AS F_ThisStep, 
                                r.F_NodeCode AS F_ThisStepId,
                                r.F_HandleStatus AS F_Status,
                                t.F_Completion,
                                t.F_CreatorUserId,
                                r.F_HandleTime AS F_CreatorTime,
                                t.F_LastModifyUserId,
                                t.F_LastModifyTime
                                FROM Flow_Task t left join
                                Flow_TaskOperatorRecord r on r.F_TaskId = t.F_Id LEFT JOIN 
                                Flow_taskoperator o ON r.F_TaskOperatorId = o.F_Id	LEFT JOIN 
                                base_user u ON u.F_Id = o.F_HandleId  WHERE 1=1 
                                AND (r.F_HandleStatus = 0 OR r.F_HandleStatus = 1) AND r.F_TaskOperatorId is not null");
                dbSql.Append("  AND r.F_HandleId = @handleId");
                parameters.Add(DataHelper.CreateParameter("@handleId", userId));
                var queryParam = input.queryJson.ToObject();
                //关键字（流程标题、流程编码）
                if (!input.keyword.IsEmpty())
                {
                    dbSql.Append(" AND (t.F_EnCode like @keyword or t.F_FullName like @keyword)");
                    parameters.Add(DataHelper.CreateParameter("@keyword", '%' + input.keyword + '%'));
                }
                //日期范围（近7天、近1月、近3月、自定义）
                if (!queryParam["startTime"].IsEmpty() && !queryParam["endTime"].IsEmpty())
                {
                    var startTime = CommonHelper.GetDateTime(queryParam["startTime"].ToString());
                    var endTime = CommonHelper.GetDateTime(queryParam["endTime"].ToString());
                    dbSql.Append(" AND r.F_HandleTime Between CONVERT(varchar(100), @startTime, 23) +' 00:00:00' and CONVERT(varchar(100), @endTime, 23) +' 23:59:59'");
                    parameters.Add(DataHelper.CreateParameter("@startTime", startTime));
                    parameters.Add(DataHelper.CreateParameter("@endTime", endTime));
                }
                //所属流程
                if (!queryParam["flowId"].IsEmpty())
                {
                    dbSql.Append(" AND t.F_FlowId = @flowId");
                    parameters.Add(DataHelper.CreateParameter("@flowId", queryParam["flowId"].ToString()));
                }
                //所属分类
                if (!queryParam["flowCategory"].IsEmpty())
                {
                    dbSql.Append(" AND t.F_FlowCategory = @flowCategory");
                    parameters.Add(DataHelper.CreateParameter("@flowCategory", queryParam["flowCategory"].ToString()));
                }
                //发起人员
                if (!queryParam["creatorUserId"].IsEmpty())
                {
                    dbSql.Append(" AND t.F_CreatorUserId = @creatorUserId");
                    parameters.Add(DataHelper.CreateParameter("@creatorUserId", queryParam["creatorUserId"].ToString()));
                }
                //默认排序
                input.sidx = "t.F_CreatorTime";
                return await PageHelper.GetPageResultAsync<FlowTaskEntity>(db, input, dbSql.ToString(), parameters.ToArray());
            }
        }
        /// <summary>
        /// 列表（抄送我的）
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <param name="requestParam">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<FlowTaskEntity>> GetCirculateList(string userId, PageInput input)
        {
            using (var db = this.Basic)
            {
                var userRelationList = (await db.GetListAsync<UserRelationEntity>(m => m.UserId == userId)).Select(m => m.ObjectId).ToList();
                var objectId = (string.Join(",", userRelationList) + "," + userId).Split(',');
                var parameters = new List<DbParameter>();
                StringBuilder dbSql = new StringBuilder();
                dbSql.Append(@"SELECT 
                                t.F_Id, 
                                t.F_ProcessId,
                                t.F_EnCode, 
                                t.F_FullName, 
                                t.F_FlowUrgent,
                                t.F_FlowId , 
                                t.F_FlowCode , 
                                t.F_FlowName, 
                                t.F_FlowCategory, 
                                t.F_StartTime, 
                                t.F_EndTime, 
                                c.F_NodeName AS F_ThisStep, 
                                c.F_NodeCode AS F_ThisStepId,
                                t.F_Status ,
                                t.F_Completion,
                                t.F_CreatorUserId,
                                c.F_CreatorTime,
                                t.F_LastModifyUserId,
                                t.F_LastModifyTime
                                FROM Flow_Task t left join
                                Flow_TaskCirculate c on c.F_TaskId = t.F_Id WHERE 1=1");
                //传阅人员
                dbSql.Append(" AND (");
                for (int i = 0; i < objectId.Length; i++)
                {
                    parameters.Add(DataHelper.CreateParameter("@objectId" + i, objectId[i]));
                    dbSql.Append("c.F_ObjectId = @objectId" + i);
                    if (objectId.Length - 1 > i)
                        dbSql.Append(" OR ");
                }
                dbSql.Append(")");
                var queryParam = input.queryJson.ToObject();
                //关键字（流程标题、流程编码）
                if (!input.keyword.IsEmpty())
                {
                    dbSql.Append(" AND (t.F_EnCode like @keyword or t.F_FullName like @keyword)");
                    parameters.Add(DataHelper.CreateParameter("@keyword", '%' + input.keyword + '%'));
                }
                //日期范围（近7天、近1月、近3月、自定义）
                if (!queryParam["startTime"].IsEmpty() && !queryParam["endTime"].IsEmpty())
                {
                    dbSql.Append(" AND c.F_CreatorTime Between CONVERT(varchar(100), @startTime, 23) +' 00:00:00' and CONVERT(varchar(100), @endTime, 23) +' 23:59:59'");
                    var startTime = CommonHelper.GetDateTime(queryParam["startTime"].ToString());
                    var endTime = CommonHelper.GetDateTime(queryParam["endTime"].ToString());
                    parameters.Add(DataHelper.CreateParameter("@startTime", startTime));
                    parameters.Add(DataHelper.CreateParameter("@endTime", endTime));
                }
                //所属流程
                if (!queryParam["flowId"].IsEmpty())
                {
                    dbSql.Append(" AND t.F_FlowId = @flowId");
                    parameters.Add(DataHelper.CreateParameter("@flowId", queryParam["flowId"].ToString()));
                }
                //所属分类
                if (!queryParam["flowCategory"].IsEmpty())
                {
                    dbSql.Append(" AND t.F_FlowCategory = @flowCategory");
                    parameters.Add(DataHelper.CreateParameter("@flowCategory", queryParam["flowCategory"].ToString()));
                }
                //发起人员
                if (!queryParam["creatorUserId"].IsEmpty())
                {
                    dbSql.Append(" AND t.F_CreatorUserId = @creatorUserId");
                    parameters.Add(DataHelper.CreateParameter("@creatorUserId", queryParam["creatorUserId"].ToString()));
                }
                //默认排序
                input.sidx = "t.F_StartTime";
                return await PageHelper.GetPageResultAsync<FlowTaskEntity>(db, input, dbSql.ToString(), parameters.ToArray());
            }
        }
        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="id">主键值、业务主键</param>
        /// <returns></returns>
        public async Task<FlowTaskEntity> GetInfo(string id)
        {
            using (var db = this.Basic)
            {
                return await db.GetEntityAsync<FlowTaskEntity>(m => m.Id == id || m.ProcessId == id);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">实体对象</param>
        public async Task Delete(FlowTaskEntity entity)
        {
            using (var db = this.Basic)
            {
                //await db.BeginTransactionAsync();
                await db.DeleteAsync(entity);
                await db.DeleteAsync<FlowTaskNodeEntity>(m => m.TaskId == entity.Id);
                await db.DeleteAsync<FlowTaskOperatorEntity>(m => m.TaskId == entity.Id);
                await db.DeleteAsync<FlowTaskOperatorRecordEntity>(m => m.TaskId == entity.Id);
                await db.DeleteAsync<FlowTaskCirculateEntity>(m => m.TaskId == entity.Id);
                //await db.CommitTransactionAsync();
            }
        }
        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public async Task<int> Create(FlowTaskEntity entity)
        {
            using (var db = this.Basic)
            {
                return await db.InsertAsync(entity);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        public async Task<int> Update(FlowTaskEntity entity)
        {
            using (var db = this.Basic)
            {
                return await db.UpdateAsync(entity);
            }
        }
        /// <summary>
        /// 根据引擎id获取列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<FlowTaskEntity>> GetTaskList(string id)
        {
            using (var db = this.Basic)
            {
                return await db.GetListAsync<FlowTaskEntity>(m => m.FlowId == id);
            }
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<FlowTaskEntity>> GetList()
        {
            using (var db = this.Basic)
            {
                return await db.GetListAsync<FlowTaskEntity>();
            }
        }
    }
}